#include "global.h"
#include <algorithm>
#include <chrono>
#include <ctime>
#include <sstream>
#include <iostream>

// Global variables
bool g_shutdown_requested = false;
int g_log_level = 1; // 0=DEBUG, 1=INFO, 2=ERROR

namespace GlobalUtils {

std::string Trim(const std::string& str) {
    size_t start = str.find_first_not_of(" \t\n\r\f\v");
    if (start == std::string::npos) return "";
    
    size_t end = str.find_last_not_of(" \t\n\r\f\v");
    if (end == std::string::npos) return str.substr(start);
    
    return str.substr(start, end - start + 1);
}

std::string ToLower(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::tolower);
    return result;
}

std::string ToUpper(const std::string& str) {
    std::string result = str;
    std::transform(result.begin(), result.end(), result.begin(), ::toupper);
    return result;
}

bool StartsWith(const std::string& str, const std::string& prefix) {
    if (str.length() < prefix.length()) return false;
    return str.substr(0, prefix.length()) == prefix;
}

bool EndsWith(const std::string& str, const std::string& suffix) {
    if (str.length() < suffix.length()) return false;
    return str.substr(str.length() - suffix.length()) == suffix;
}

int64_t GetCurrentTimeMillis() {
    auto now = std::chrono::system_clock::now();
    auto duration = now.time_since_epoch();
    return std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
}

std::string FormatTime(time_t time, const std::string& format) {
    char buffer[256];
    struct tm* tm_info = localtime(&time);
    strftime(buffer, sizeof(buffer), format.c_str(), tm_info);
    return std::string(buffer);
}

const char* GetErrorString(int error_code) {
    switch (error_code) {
        case ERR_SUCCESS: return "Success";
        case ERR_SOCKET: return "Socket error";
        case ERR_BIND: return "Bind error";
        case ERR_LISTEN: return "Listen error";
        case ERR_ACCEPT: return "Accept error";
        case ERR_POLL: return "Poll error";
        case ERR_TIMEOUT: return "Timeout error";
        case ERR_MEMORY: return "Memory error";
        default: return "Unknown error";
    }
}

void LogError(const std::string& message) {
    if (g_log_level <= 2) {
        auto now = std::chrono::system_clock::now();
        auto time_t_now = std::chrono::system_clock::to_time_t(now);
        std::cerr << "[" << FormatTime(time_t_now, "%Y-%m-%d %H:%M:%S") 
                  << "] ERROR: " << message << std::endl;
    }
}

void LogNotice(const std::string& message) {
    if (g_log_level <= 3) {
        auto now = std::chrono::system_clock::now();
        auto time_t_now = std::chrono::system_clock::to_time_t(now);
        std::cout << "[" << FormatTime(time_t_now, "%Y-%m-%d %H:%M:%S") 
                  << "] NOTICE: " << message << std::endl;
    }
}

void LogWarning(const std::string& message) {
    if (g_log_level <= 2) {
        auto now = std::chrono::system_clock::now();
        auto time_t_now = std::chrono::system_clock::to_time_t(now);
        std::cout << "[" << FormatTime(time_t_now, "%Y-%m-%d %H:%M:%S") 
                  << "] WARNING: " << message << std::endl;
    }
}

void LogInfo(const std::string& message) {
    if (g_log_level <= 1) {
        auto now = std::chrono::system_clock::now();
        auto time_t_now = std::chrono::system_clock::to_time_t(now);
        std::cout << "[" << FormatTime(time_t_now, "%Y-%m-%d %H:%M:%S") 
                  << "] INFO: " << message << std::endl;
    }
}

void LogDebug(const std::string& message) {
    if (g_log_level <= 0) {
        auto now = std::chrono::system_clock::now();
        auto time_t_now = std::chrono::system_clock::to_time_t(now);
        std::cout << "[" << FormatTime(time_t_now, "%Y-%m-%d %H:%M:%S") 
                  << "] DEBUG: " << message << std::endl;
    }
}

} // namespace GlobalUtils